package com.xinyue.ext.reader.bean;

import org.dom4j.Element;

import com.xinyue.ext.EnumData;
import com.xinyue.ext.Label;
import com.xinyue.ext.data.FieldData;
import com.xinyue.ext.exception.BeanException;
import com.xinyue.ext.reader.ParamHolder;
import com.xinyue.ext.util.StringUtil;

public abstract class BeanContext implements Label, EnumData{
	
	//参数集
	protected static ParamHolder holder;
	
	/**读取ID、property、rely信息
	 */
	public abstract void read(Element e) throws BeanException;
	
	/**
	 * 读取公共属性
	 * @param e
	 * @return
	 * @throws BeanException
	 */
	protected FieldData commonRead(Element e) throws BeanException {
		//属性
		FieldData field = new FieldData();
		
		String name = e.attributeValue(name_);//属性名称
		String type = e.attributeValue(type_);//属性类型
		if(StringUtil.isNull(name)) {
			throw new BeanException("id或者property标签没有定义name属性或其值为空", holder.getException());
		}
		if(StringUtil.isNull(type)) {
			throw new BeanException("id或者property标签没有定义type属性或其值为空", holder.getException());
		}else if(!javaTypeVdt(type)) {
			throw new BeanException("id或者property标签type属性值非法：" + type, holder.getException());
		}
		field.setName(name);
		field.setType(type);
		field.setDesc(e.attributeValue(desc_));//描述信息
		
		//注解信息
		columnOperate(e, field);
		
		return field;
	}
	
	/**属性类型验证
	 */
	private boolean javaTypeVdt(String type) {
		if(javaType[0].equals(type)) {//Date
			holder.getBeanImpt().add("java.util.Date");
			return true;
		}else if(javaType[1].equals(type)) {//BigDecimal
			holder.getBeanImpt().add("java.math.BigDecimal");
			return true;
		}else if(javaType[2].equals(type)) {//Blob
			holder.getBeanImpt().add("java.sql.Blob");
			return true;
		}else {//其他非引用类型
			for (int i = 3; i < javaType.length; i++) {
				if(javaType[i].equals(type)) {
					return true;
				}
			}
		}
		return false;
	}
	
	
	/**
	 * 获取column注解信息
	 * @Column注解设置
	 * name：字段名
	 * unique：是否唯一
	 * nullable：是否可以为空
	 * inserttable：是否可以插入
	 * updateable：是否可以更新
	 * length: 长度
	 * columnDefinition: 自定义属性类型
	 * transient：瞬时字段：不需要与数据库映射的字段，在保存的时候不需要保存倒数据库
	 */
	private void columnOperate(Element e, FieldData field) {
		String dec = ", ";//分隔符号
		String link = " = ";//连接符
		String column = "";//column数据
		
		//name：字段名
		if(!StringUtil.isNull(e.attributeValue(t_name_))) {
			field.setDbName(e.attributeValue(t_name_));
			column += dec + name_ + " = \"" + e.attributeValue(t_name_) + "\"";
		}
		//长度
		if(!StringUtil.isNull(e.attributeValue(length_))) {
			field.setLength(e.attributeValue(length_));
			column += dec + length_ + link + e.attributeValue(length_);
		}
		//unique：是否唯一
		if(!StringUtil.isNull(e.attributeValue(unique_))) {
			field.setUnique(Boolean.valueOf(e.attributeValue(unique_)));
			column += dec + unique_ + link + e.attributeValue(unique_);
		}
		//nullable：是否可以为空
		if(!StringUtil.isNull(e.attributeValue(nullable_))) {
			field.setNullable(Boolean.valueOf(e.attributeValue(nullable_)));
			column += dec + nullable_ + link + e.attributeValue(nullable_);
		}
		//inserttable：是否可以插入
		if(!StringUtil.isNull(e.attributeValue(insertable_))) {
			column += dec + insertable_ + link + e.attributeValue(insertable_);
		}
		//updateable：是否可以更新
		if(!StringUtil.isNull(e.attributeValue(updatable_))) {
			column += dec + updatable_+ link + e.attributeValue(updatable_);
		}
		//columnDefinition：自定义字段类型
		if(!StringUtil.isNull(e.attributeValue(columnDefinition_))) {
			field.setDefinition(e.attributeValue(columnDefinition_));
			column += dec + columnDefinition_+ link + e.attributeValue(columnDefinition_);
		}
		//transient：是否瞬时字段
		if(!StringUtil.isNull(e.attributeValue(transient_))) {
			Boolean flag = Boolean.valueOf(e.attributeValue(transient_));
			if(flag) {
				field.setAnn_transient(true);
				holder.getBeanImpt().add("javax.persistence.Transient");
			}
		}
		
		if(column.length() > 0) {
			//属性上的注解
			column = "@Column(" + column.substring(2, column.length()) + ")";
			
			field.setAnn_column(column);
			holder.getBeanImpt().add("javax.persistence.Column");
		}
	}
}
